package com.samskievert.cactusboom;

import com.threerings.media.sprite.ImageSprite;
import java.awt.Graphics2D;

import java.awt.Color;
import java.awt.geom.AffineTransform;
import java.awt.Dimension;
import java.awt.Point;
import com.threerings.media.util.LinePath;
import java.util.Iterator;
import java.util.ArrayList;

import com.threerings.media.image.BufferedMirage;
import com.threerings.media.image.Mirage;

/**
 *  The spike sprite is really for display purposes only.  When created, we tell the
 *  sprite who its parent was and which spike on that parent this sprite represents.
 *  From these two, we can get the original position, color, and direction.
 *
 *  We feed in the target location from the logic class and this spike animates from
 *  Point A to Point B.  When it reaches its destination, it sends a call for the 
 *  target Sprite to insert a spike of this spike's color into the target slot.
 *
 *  Concurrent calls just overwrite the currently colored spike.
 */
public class SpikeSprite extends ImageSprite
{
    public static final int SIZE = 48;
    public static final float SPEED = 175;  //the amount of time in millis needed to cross one unit of Size
    
    public boolean notSpent = true;
    
    private int _startX;
    private int _startY;
    
    private int _color;
    private int _angle;
    
    private int _numSpikes;
    private Dimension _boardsize;
    
    private BufferedMirage _image;
    
    private int _myDX;
    private int _myDY;
    
    private CBObject _gameobj;
    private CBBoardView _bv;
    
    public SpikeSprite (CBObject.Cactus cactus, int whichSpike, Dimension boardSize, CBObject gameobj, CBBoardView bv, BufferedMirage image)
    {
        super(image);
        setLocation(cactus.x*SIZE, cactus.y*SIZE);
        _image = image;
        _color = cactus.spikes[whichSpike];
        _angle = whichSpike;
        _numSpikes = cactus.spikes.length;
        _startX = cactus.x;
        _startY = cactus.y;
        _gameobj = gameobj;
        _boardsize = boardSize;
        _bv = bv;
        
        int[] DX = { 0, -1, -1, -1,  0,  1, 1, 1 };
        int[] DY = { 1,  1,  0, -1, -1, -1, 0, 1 };
                
        if(_numSpikes == 4){
            DX = new int[] { 0, -1,  0, 1 };
            DY = new int[] { 1,  0, -1, 0 };
        }
        
        //used later to see who's in front of us and check collision
        _myDX = DX[whichSpike];
        _myDY = DY[whichSpike];
                
        int tX = cactus.x;
        int tY = cactus.y;
        
        while(tX > -1 && tX < boardSize.width && tY > -1 && tY < boardSize.height)
        {
            tX += DX[whichSpike];
            tY += DY[whichSpike];
        }
     
        double dist = Math.sqrt(Math.pow(tX - cactus.x, 2.0) + Math.pow(tY - cactus.y, 2.0));
        move(new LinePath(new Point(tX*SIZE, tY*SIZE), Math.round(dist*SPEED)));
    }
    
    @Override //from Sprite
    public void tick(long tickStamp)
    {
        super.tick(tickStamp);
     
        if(notSpent)
        {
            int tx = 0;
            int ty = 0;
            
            //get my relative x/y
            if(_myDX < 0){
                tx = (getX() - _myDX*16) / SIZE;
            }else{
                tx = (getX() + _myDX*32) / SIZE;
            }
            
            if(_myDY < 0){
                ty = (getY() - _myDY*16) / SIZE;
            }else{
                ty = (getY() + _myDY*32) / SIZE;
            }
            
            if(getX() < 0 || getY() < 0 || getX() > (_boardsize.width-1)*SIZE || getY() >(_boardsize.height-1)*SIZE) notSpent = false;

            ArrayList<CBObject.Cactus> updateList = new ArrayList<CBObject.Cactus>();
            
            Iterator p = _gameobj.pieces.iterator();
            while(p.hasNext()){
              CBObject.Cactus cactus = (CBObject.Cactus)p.next();
              if(cactus.x == tx && cactus.y == ty && cactus.active)
              {
                  if(cactus.x == _startX && cactus.y == _startY){
                      //This was causing some spikes to not fire...
                      //System.out.println("Hit parent.");
                  }else{
                  //System.out.println("Collision at (" + getX() + "," + getY() + ") with tile (" + tx + "," + ty + ")");
                  cactus.addSpike(_color);
                  updateList.add(cactus);
                  notSpent = false;
                  }
              }
              //_sprites.get(cactus.getKey()).updateCactus(cactus);
            }
            
            for(CBObject.Cactus cactus : updateList){
                if(!_gameobj.localsOnly){
                    //if(!_gameobj.isFull(cactus))
                    _bv.quickUpdateCactus(cactus);
                }else{
                    _bv.killCactusQuietly(cactus);
                }
            }
            
            ArrayList<CBObject.Cowboy> playerHits = new ArrayList<CBObject.Cowboy>();
            p = _gameobj.cowboys.iterator();
            while(p.hasNext()){
              CBObject.Cowboy cowboy = (CBObject.Cowboy)p.next();
              if(cowboy.x == tx && cowboy.y == ty)
              {
                  //System.out.println("Shot to the heart!");
                  //_gameobj.manager.invoke("spikeHitCowboy", cowboy);
                  //notSpent = false;
              }
            }
        
        }
    }
    

    
    @Override // from Sprite
    public void paint (Graphics2D gfx)
    {
        if(notSpent)
        {
            Color[] COLORLIST = new Color[] {Color.blue, Color.red, Color.green, Color.orange};
            
            int px = _bounds.x + 12, py = _bounds.y + 12;
            int pwid = _bounds.width - 24, phei = _bounds.height - 24;
        
            //store the current position
            AffineTransform currentRot = gfx.getTransform();

            //translate to the middle of the sprite 
            gfx.translate(px + pwid/2,py + pwid/2);
            //rotate the proper amount
            gfx.rotate(Math.PI + 2.0 * _angle * Math.PI / _numSpikes);
            //draw the image(offset so that the center is in the correct place)
            _image.paint(gfx,-24,-24);
            /*
            //draw the spike
            gfx.setColor(COLORLIST[_color]);   
            gfx.fillRect(-2,pwid/2,4,8);
            gfx.setColor(Color.black);
            gfx.drawRect(-2,pwid/2,4,8);
             **/
        
            //reset to the correct transformation
            gfx.setTransform(currentRot);
        }

    }
    
  }


